<script>
import { Reading, MoreFilled } from "@element-plus/icons-vue";
import ApiEdit from "./ApiEdit.vue";
import MarkdownEdit from "./MarkdownEdit.vue";
import RtfEdit from "./RtfEdit.vue";
import store from "../../../store/index.js";
import Request from "../../../utils/Request.js";
import ApiView from "../../view/ApiView.vue";
import MarkdownView from "../../view/MarkdownView.vue";
import RtfView from "../../view/RtfView.vue";
import MindMapEdit from "./MindMapEdit.vue";
import MindMapView from "../../view/MindMapView.vue";
import MarkdownIt from "markdown-it";

export default {
  name: "EditTab",
  components: {
    RtfEdit,
    MarkdownEdit,
    ApiEdit,
    Reading,
    MoreFilled,
    ApiView,
    RtfView,
    MarkdownView,
    MindMapEdit,
    MindMapView,
  },
  props: {
    tabPlaneData: Array,
    selectTabName: String,
  },
  emits: ["update:selectTabName"],
  computed: {
    store() {
      return store;
    },
    mySelectTabName: {
      get() {
        return this.selectTabName;
      },
      set(value) {
        this.$emit("update:selectTabName", value);
      },
    },
    needRemoveTabId() {
      return store.state.needRemoveTabId;
    },
    aiReaderContentHTML() {
      return this.markdown.render(this.aiReaderContent == null ? "" : this.aiReaderContent);
    },
  },
  watch: {
    needRemoveTabId(nV, oV) {
      if (nV !== oV) {
        this.removeTab(nV);
      }
    },
    mySelectTabName(nV, oV) {
      this.openedTabName = nV;
    },
    // 用于监听aiReaderDrawer，实现实时获取ai总结结果
    aiReaderDrawer(nV, oV) {
      console.log(nV, oV);
      if (nV == true && oV == false && this.aiReaderSummaryGenerating == true) {
        // 启动定时器，轮询ai总结结果
        let index = this.getPlaneIndexById(this.openedTabName);
        let plane = this.tabPlaneData[index];
        this.aiReaderTimer = setInterval(() => {
          this.checkAndSettingSummaryGenerating(plane);
        }, 3000);
      } else if (nV == false && oV == true) {
        // 关闭定时器
        if (this.aiReaderTimer != null) {
          clearInterval(this.aiReaderTimer);
          this.aiReaderTimer = null;
        }
      }
    }
  },
  data() {
    return {
      isYouEdit: {},
      isYouEditTimer: {},
      versionSaveDialog: false,
      versionReadDialog: false,
      openedTabName: "",
      versionReadData: {
        pageSize: 6,
        currentPage: 1,
        totalPage: 0,
        list: [
          {
            editor: "Wshape1",
            name: "文档",
            version: "v1.0.0",
            remark: "初始版本",
            time: "2022-04-01 11:00",
          },
          {
            editor: "Wshape2",
            name: "文档",
            version: "v1.0.1",
            remark:
              "修复了xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            time: "2022-04-02 12:00",
          },
        ],
      },
      versionSaveForm: {
        name: "",
        version: "",
        remark: "",
      },
      versionSaveFormRule: {
        version: [
          { required: true, message: "请输入版本号", trigger: "blur" },
          { min: 0, max: 100, message: "版本号应该不大于100", trigger: "blur" },
          {
            validator: (rule, value, callback) => {
              this.queryVersion(value)
                .then(({ data }) => {
                  if (data.code === 0) {
                    if (data.data != null) callback(new Error("该版本已存在"));
                    else callback();
                  } else {
                    callback(new Error(data.msg));
                  }
                })
                .catch((err) => {
                  callback(err);
                });
            },
            trigger: "blur",
          },
        ],
        remark: [
          { required: false, message: "请输入备注", trigger: "blur" },
          {
            min: 0,
            max: 200,
            message: "备注长度应该不大于200",
            trigger: "blur",
          },
        ],
      },
      versionViewMoreDialog: {
        enable: false,
        title: "",
        which: "",
        id: "",
        apiTags: [],
        apiContents: {},
        content: "",
      },
      concurrentEditWarning: {},
      projectId: this.$route.params.projectId,
      aiReaderDrawer: false,
      aiReaderContent: null,
      aiReaderDoc: "",
      aiReaderCreateTime: null,
      aiReaderSummaryGenerating: false,
      aiReaderTimer: null,
      markdown: new MarkdownIt(),
    };
  },
  methods: {
    getTypeStrToInt(type) {
      if (type === "api") return 0;
      else if (type === "markdown") return 1;
      else if (type === "rtf") return 2;
      else if (type === "mindmap") return 4;
      else return -1;
    },
    queryVersion(value) {
      let index = this.getPlaneIndexById(this.openedTabName);

      let plane = this.tabPlaneData[index];

      return Request({
        url: "/api/project/doc/version/query",
        method: "post",
        data: {
          projectId: this.$route.params.projectId,
          docId: plane.id,
          version: value,
          docType: this.getTypeStrToInt(plane.type),
        },
      });
    },
    getPlaneIndexById(id) {
      for (let i = 0; i < this.tabPlaneData.length; i++) {
        if (this.tabPlaneData[i].id === id) return i;
      }
      return -1;
    },
    removeTab(id) {
      let index = this.getPlaneIndexById(id);
      if (index !== -1) {
        let plane = this.tabPlaneData[index];
        // console.log(plane);
        // console.log(this.isYouEditTimer);
        this.stopEdit(plane);
        this.tabPlaneData.splice(index, 1);
        store.state.planeTabIsModified.splice(index, 1);
        this.openedTabName = "";
      }
    },

    versionSave() {
      this.$refs.versionSaveForm.validate((valid) => {
        if (valid) {
          let index = this.getPlaneIndexById(this.openedTabName);
          let plane = this.tabPlaneData[index];
          Request({
            url: "/api/project/doc/version/save",
            method: "post",
            data: {
              projectId: this.$route.params.projectId,
              docId: this.openedTabName,
              version: this.versionSaveForm.version,
              remark: this.versionSaveForm.remark,
              docType: this.getTypeStrToInt(plane.type),
            },
          }).then(({ data }) => {
            if (data.code === 0) {
              this.$message.success("保存版本成功");
              this.versionSaveDialog = false;
            } else {
              this.$message.error(data.msg);
            }
          });
        } else {
          this.$message.error("请填写完整信息");
          return false;
        }
      });
    },

    versionRead() {
      // this.$message.success("查看版本");
      // 查看版本
      let index = this.getPlaneIndexById(this.openedTabName);
      let plane = this.tabPlaneData[index];
      Request({
        url:
          "/api/project/doc/version/list?page=" +
          this.versionReadData.currentPage +
          "&limit=" +
          this.versionReadData.pageSize,
        method: "post",
        data: {
          projectId: this.$route.params.projectId,
          docId: this.openedTabName,
          docType: this.getTypeStrToInt(plane.type),
        },
      }).then(({ data }) => {
        if (data.code === 0) {
          this.versionReadData = data.data;
        } else {
          this.$message.error(data.msg);
          this.versionReadData = {};
        }
      });
    },

    versionCtrl(command) {
      if (this.openedTabName === "") {
        this.$message.info("请先选择一个文档再进行版本操作");
        return;
      }

      if (command === "save") {
        // this.$message.success("保存版本");
        // console.log(this.openedTabName)

        let index = this.getPlaneIndexById(this.openedTabName);
        if (index != -1 && store.state.planeTabIsModified[index]) {
          this.$messsage.info("请先保存文档再进行版本操作");
          return;
        }

        let data = this.tabPlaneData[index];
        this.versionSaveForm.name = data.name;
        this.versionSaveForm.version = "";
        this.versionSaveForm.remark = "";

        // 打开保存版本 dialog
        this.versionSaveDialog = true;
      } else if (command === "read") {
        // this.$message.success("查看版本");
        this.versionRead();
        this.versionReadDialog = true;
      }
    },
    versionRemove(row) {
      Request({
        url: "/api/project/doc/version/delete",
        method: "post",
        data: {
          projectId: this.$route.params.projectId,
          id: row.id,
        },
      }).then(({ data }) => {
        if (data.code === 0) {
          this.$message.success("删除版本成功");
          this.versionRead();
        } else {
          this.$message.error(data.msg);
        }
      });
    },
    versionViewMore(row) {
      // console.log(row);
      let index = this.getPlaneIndexById(this.openedTabName);
      let plane = this.tabPlaneData[index];
      Request({
        url: "/api/project/doc/version/get",
        method: "post",
        data: {
          projectId: this.$route.params.projectId,
          docId: this.openedTabName,
          docType: this.getTypeStrToInt(plane.type),
          version: row.version,
        },
      }).then(({ data }) => {
        if (data.code === 0) {
          // console.log(data);
          if (data.data.docType == 0) {
            const content = JSON.parse(data.data.content);
            // console.log(content);
            this.versionViewMoreDialog.apiContents = content.apiData;
            this.versionViewMoreDialog.apiTags = content.tags;
          } else {
            this.versionViewMoreDialog.content = data.data.content;
          }
          this.versionViewMoreDialog.id = this.openedTabName;
          this.versionViewMoreDialog.title =
            row.docName + " · " + row.version + " · " + row.editorName;
          this.versionViewMoreDialog.which = plane.type;
          this.versionViewMoreDialog.enable = true;
        } else {
          this.$message.error(data.msg);
        }
      });
    },
    editTimerCallback() {
      const key = arguments[0].type + arguments[0].id;
      Request({
        url: "/api/project/doc/startEdit",
        method: "post",
        data: {
          projectId: this.$route.params.projectId,
          docId: arguments[0].id,
          docType: arguments[0].type,
        },
      }).then(({ data }) => {
        if (data.code === 0) {
          if (
            data.data != null &&
            String(data.data) == String(this.$store.state.user.id)
          ) {
            //
            if (this.concurrentEditWarning[key])
              delete this.concurrentEditWarning[key];
          } else {
            if (!this.concurrentEditWarning[key]) {
              ElMessageBox.alert(
                "该文档的编辑者不是您，您的文档保存可能失败，可以尝试重新打开文档或刷新页面",
                "《" + arguments[0].name + "》编辑提示",
                {
                  confirmButtonText: "确定",
                  type: "warning",
                }
              );
              this.concurrentEditWarning[key] = true;
            }
          }
        }
      });
    },
    startEdit(item) {
      // console.log(item);
      Request({
        url: "/api/project/doc/startEdit",
        method: "post",
        data: {
          projectId: this.$route.params.projectId,
          docId: item.id,
          docType: item.type,
        },
      }).then(({ data }) => {
        if (data.code === 0) {
          // console.log(data);
          if (
            data.data != null &&
            String(data.data) == String(this.$store.state.user.id)
          ) {
            const key = item.type + item.id;
            if (!this.isYouEdit[key]) {
              this.isYouEdit[key] = true;
              this.isYouEditTimer[key] = setInterval(
                this.editTimerCallback,
                10000,
                item
              );
            }
          } else {
            this.$message.error("该文档正在被其他人编辑中");
          }
        } else {
          this.$message.error(data.msg);
        }
      });
    },
    stopEdit(item) {
      const key = item.type + item.id;
      if (this.isYouEdit[key] != null) {
        clearInterval(this.isYouEditTimer[key]);
        delete this.isYouEdit[key];
        delete this.isYouEditTimer[key];
        Request({
          url: "/api/project/doc/stopEdit",
          method: "post",
          data: {
            projectId: this.projectId,
            docId: item.id,
            docType: item.type,
          },
        }).then(({ data }) => {
          if (data.code === 0) {
          } else {
            this.$message.error(data.msg);
          }
        });
      }
    },
    getSummary(plane) {
      this.aiReaderSummaryGenerating = false;
      this.aiReaderContent = null;
      this.aiReaderCreateTime = null;
      Request({
        url: "/api/project/doc/getSummary",
        method: "post",
        data: {
          projectId: this.projectId,
          docId: this.openedTabName,
          docType: plane.type,
        },
      }).then(({ data }) => {
        if (data.code === 0) {
          this.aiReaderContent = data.data.summary;
          this.aiReaderCreateTime = data.data.createTime;
          if (data.data.generating == true) {
            this.aiReaderSummaryGenerating = true;
            if (this.aiReaderTimer == null) {
              this.aiReaderTimer = setInterval(() => {
                this.checkAndSettingSummaryGenerating(plane);
              }, 3000);
            }
          }
        } else {
          this.$message.error(data.msg);
        }
      });
    },
    checkAndSettingSummaryGenerating(plane) {
      Request({
        url: "/api/project/doc/isSummaryGenerating",
        method: "post",
        data: {
          projectId: this.projectId,
          docId: this.openedTabName,
          docType: plane.type,
        },
      }).then(({ data }) => {
        if (data.code === 0) {
          if (data.data.generating == true) {
            this.aiReaderSummaryGenerating = true;
          } else if (data.data.generating == false && this.aiReaderSummaryGenerating == true) {
            this.aiReaderSummaryGenerating = false;
            this.getSummary(plane);
            if (this.aiReaderTimer != null) {
              clearInterval(this.aiReaderTimer);
              this.aiReaderTimer = null;
            }
            this.$message.success("AI总结成功");
          }
        } else {
          if (this.aiReaderTimer != null) {
            clearInterval(this.aiReaderTimer);
            this.aiReaderTimer = null;
          }
          this.$message.error(data.msg);
          this.aiReaderSummaryGenerating = false;
        }
      });
    },
    openAiRead() {
      this.aiReaderDrawer = true;
      let index = this.getPlaneIndexById(this.openedTabName);
      let plane = this.tabPlaneData[index];
      if (this.openedTabName != this.aiReaderDoc) {
        // 切换文档时
        // if (plane.type != "rtf" && plane.type != "markdown") {
        //   this.aiReaderContent = "## 暂不支持该类型文档的AI阅读助手";
        //   this.aiReaderSummaryGenerating = true;
        //   this.aiReaderCreateTime = null;
        //   return;
        // }
        this.aiReaderDoc = this.openedTabName;
        this.getSummary(plane);
      } else {
        // 
        this.checkAndSettingSummaryGenerating(plane);
      }
    },
    genrateAiSummary() {
      let index = this.getPlaneIndexById(this.openedTabName);
      let plane = this.tabPlaneData[index];
      // if (plane.type != "rtf" && plane.type != "markdown") {
      //   this.$message.console.warn("暂不支持该类型文档的AI阅读助手");
      //   return;
      // }

      Request({
        url: "/api/project/doc/aiSummary",
        method: "post",
        data: {
          projectId: this.projectId,
          docId: this.openedTabName,
          docType: plane.type,
        },
      }).then(({ data }) => {
        if (data.code === 0) {
          this.aiReaderSummaryGenerating = true;

          // 启动定时器，轮询ai总结结果
          let index = this.getPlaneIndexById(this.openedTabName);
          let plane = this.tabPlaneData[index];
          this.aiReaderTimer = setInterval(() => {
            this.checkAndSettingSummaryGenerating(plane);
          }, 3000);

          this.$message.success("AI正在总结，预计1-3分钟完成（此界面可以关闭）");

        } else {
          this.$message.error(data.msg);
        }
      });

    },
  },
  beforeUnmount() {
    for (const item of this.tabPlaneData) {
      this.stopEdit(item);
    }
  },
};
</script>

<template>
  <el-tabs v-model="openedTabName" type="card" closable :addable="openedTabName != ''" @tab-remove="removeTab"
    v-show="tabPlaneData.length > 0">
    <template #add-icon>
      <el-tooltip class="tab-add-icon-left" effect="dark" content="AI阅读助手" placement="top">
        <el-icon size="large" @click="openAiRead()">
          <svg style="width: 150%; height: 150%; position: absolute" t="1736777038762" class="icon"
            viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4296" width="256"
            height="256">
            <path
              d="M300.8 812.8h424c48 0 88-40 88-88V300.8c0-48-40-88-88-88H300.8c-48 0-88 40-88 88v424c0 48 38.4 88 88 88z m-48-512c0-25.6 20.8-48 48-48h424c25.6 0 48 20.8 48 48v424c0 25.6-20.8 48-48 48H300.8c-25.6 0-48-20.8-48-48V300.8z"
              fill="#2c2c2c" p-id="4297"></path>
            <path
              d="M652.8 334.4h40v355.2h-40zM384 576h142.4l43.2 113.6H608l-136-355.2h-33.6l-139.2 355.2h40L384 576z m72-182.4l54.4 142.4H400l56-142.4z"
              fill="#2c2c2c" p-id="4298"></path>
          </svg>
        </el-icon>
      </el-tooltip>

      <el-dropdown @command="versionCtrl" size="large" class="tab-add-icon-right">
        <el-icon size="large">
          <MoreFilled />
        </el-icon>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item command="save">保存版本</el-dropdown-item>
            <el-dropdown-item command="read">查看版本</el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
    </template>

    <el-tab-pane v-for="(item, index) in tabPlaneData" :key="item.id" :label="store.state.planeTabIsModified[index] ? item.name + '*' : item.name
      " :name="item.id" lazy>
      <!-- 蒙层 -->
      <div v-if="!(isYouEdit[item.type + item.id] == true)">
        <svg style="
            height: 100%;
            width: 100%;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 2002;
          ">
          <rect x="0" y="0" width="100%" height="100%" fill="rgba(0, 0, 0, 0.5)" rx="5" ry="5" />
        </svg>
        <el-button type="primary" style="
            position: absolute;
            z-index: 2003;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
          " plain @click="startEdit(item)">
          编辑
        </el-button>
      </div>

      <ApiEdit :id="item.id" :index="index" v-if="item.type === 'api'" />
      <MarkdownEdit :id="item.id" :index="index" v-else-if="item.type === 'markdown'" />
      <RtfEdit :id="item.id" :index="index" v-else-if="item.type === 'rtf'" />
      <MindMapEdit :id="item.id" :index="index" v-else-if="item.type === 'mindmap'" />
    </el-tab-pane>
  </el-tabs>

  <!-- 保存版本 dialog -->
  <el-dialog v-model="versionSaveDialog" title="保存版本" width="500">
    <el-form ref="versionSaveForm" :model="versionSaveForm" label-width="auto" :rules="versionSaveFormRule">
      <el-form-item label="文档名">
        <el-input v-model="versionSaveForm.name" autocomplete="off" disabled />
      </el-form-item>
      <el-form-item label="版本" prop="version">
        <el-input v-model="versionSaveForm.version" autocomplete="off" />
      </el-form-item>
      <el-form-item label="备注" prop="remark">
        <el-input v-model="versionSaveForm.remark" autocomplete="off" />
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="versionSaveDialog = false" style="margin-left: auto">取消</el-button>
        <el-button type="primary" @click="versionSave"> 保存 </el-button>
      </div>
    </template>
  </el-dialog>

  <!-- 查看版本 dialog -->
  <el-dialog v-model="versionReadDialog" title="版本记录" width="1000" :close-on-click-modal="false">
    <el-table :data="versionReadData.list" style="width: 100%">
      <template #header></template>
      <el-table-column>
        <template #default="scope">
          <div style="align-items: left">
            <el-row>
              <el-text>{{ scope.row.docName }}</el-text>
              <el-text size="large" tag="b">&nbsp;·&nbsp;</el-text>
              <el-text size="large" tag="b">{{ scope.row.version }}</el-text>
            </el-row>
            <el-row>
              <el-text size="small" type="info">{{
                scope.row.editorName
              }}</el-text>
              <el-text size="small" tag="b">&nbsp;·&nbsp;</el-text>
              <el-text size="small" type="info">{{
                scope.row.saveTime
              }}</el-text>
            </el-row>
            <el-row>
              <el-tooltip effect="dark" :show-after="1000" :content="scope.row.remark" placement="bottom"
                popper-class="tooltip-content">
                <el-text size="small" type="info" truncated>
                  {{ scope.row.remark }}
                </el-text>
              </el-tooltip>
            </el-row>
          </div>
        </template>
      </el-table-column>

      <el-table-column fixed="right" align="right" :close-on-click-modal="false">
        <template #header></template>
        <template #default="scope">
          <el-popconfirm title="是否要删除该版本？" @confirm="versionRemove(scope.row)" confirm-button-text="是"
            cancel-button-text="否" confirm-button-type="danger">
            <template #reference>
              <el-button size="small" type="danger"> 删除 </el-button>
            </template>
          </el-popconfirm>
          <el-button size="small" @click="versionViewMore(scope.row)">
            查看
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <template #footer>
      <el-row class="dialog-footer" style="width: 100%">
        <el-pagination layout="prev, pager, next" :total="versionReadData.total"
          v-model:page-size="versionReadData.pageSize" :page-count="versionReadData.totalPage"
          v-model:current-page="versionReadData.currentPage" :default-current-page="1" :default-page-size="8"
          :page-sizes="[8, 16, 24, 32, 48]" hide-on-single-page @update:current-page="(val) => versionRead()"
          @update:page-size="(val) => versionRead()" />
        <el-button @click="versionReadDialog = false" style="margin-left: auto">关闭</el-button>
      </el-row>
    </template>
  </el-dialog>

  <el-dialog v-model="versionViewMoreDialog.enable" :title="versionViewMoreDialog.title" :fullscreen="true"
    :close-on-click-modal="false" @close="versionViewMoreDialog = { enable: false, which: '' }">
    <ApiView v-if="versionViewMoreDialog.which === 'api'" :id="versionViewMoreDialog.id"
      :api-contents="versionViewMoreDialog.apiContents" :api-tags="versionViewMoreDialog.apiTags" />
    <MarkdownView v-else-if="versionViewMoreDialog.which === 'markdown'" :id="versionViewMoreDialog.id"
      :markdown-text="versionViewMoreDialog.content" />
    <RtfView v-else-if="versionViewMoreDialog.which === 'rtf'" :id="versionViewMoreDialog.id"
      :rtf-text="versionViewMoreDialog.content" />

    <MindMapView v-else-if="versionViewMoreDialog.which === 'mindmap'" :id="versionViewMoreDialog.id"
      :mindmap-text="versionViewMoreDialog.content" style="height: 100vh" />
  </el-dialog>

  <el-drawer v-model="aiReaderDrawer" title="AI · 阅读助手" direction="rtl">
    <el-text>
      <span v-html="aiReaderContentHTML"></span>
    </el-text>

    <template #footer>
      <el-text v-show="aiReaderCreateTime != null" style="margin-right: 10px;">
        生成时间：{{ aiReaderCreateTime }}
      </el-text>
      <el-button :diabled="aiReaderSummaryGenerating" type="primary" :loading="aiReaderSummaryGenerating"
        @click="genrateAiSummary()">{{ aiReaderContent == null ? 'AI总结' : '重新AI总结'
        }}</el-button>
    </template>
  </el-drawer>
</template>

<style scoped>
.tooltip-content {
  /** 自动换行 */
  width: 400px;
  white-space: normal;
  word-break: break-all;
}

.dialog-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

:deep(.el-tabs__new-tab) {
  border: 0;
  border-radius: 0;
  width: 50px;
  justify-content: space-between;
}

.tab-add-icon-left {
  width: 20px;
  height: 100%;
  border: 1px solid var(--el-border-color);
  border-radius: 3px;
}

.tab-add-icon-right {
  width: 20px;
  height: 100%;
  border: 1px solid var(--el-border-color);
  border-radius: 3px;
}
</style>